package study.async.springboot.controller;

import cn.hutool.core.thread.ThreadUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import study.eggs.result.Result;
import study.eggs.result.Results;

import javax.servlet.AsyncContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * SpringMVC 实现了 DeferredResult 和 Servlet3.0 提供的 AsyncContext 其实没有多大区别，
 * 但从使用层面上来看，AsyncContext 更加的灵活，例如其可以自定义响应码，
 * 而 DeferredResult 在上层做了封装，可以快速的帮助开发者实现一个异步响应，但没法细粒度地控制响应。
 */
@Slf4j
@RestController
public class _4_AsyncContextController {

    @RequestMapping("/asyncContext")
    public Result asyncContext(HttpServletRequest request, HttpServletResponse response) {
        log.info(">>>>>> i am controller111m");

        //step-1: 一定要由 http 线程调用，否则离开后容器会立即发送响应
        AsyncContext asyncContext = request.startAsync();
        //超时不准，只能自己控制
        asyncContext.setTimeout(0L);

        //step-2:
//        asyncContext.addListener();

        //step-3:
        asyncContext.start(() -> {
            ThreadUtil.sleep(4000);
            log.info(">>>>>> i am Business logic");
//                WebUtils.write(asyncContext.getResponse(), Results.ok());

            //step-4: 异步请求完成通知，此时整个请求才完成
            asyncContext.complete();
        });
        log.info(">>>>>> i am controller222");
        return Results.ok();
    }
}
